/**
 * Project  : Looker
 * Package  : net.freestu.looker.monitor
 * File     : Fetcher.java
 * Author   : solosky < solosky772@qq.com >
 * Date     : Aug 23, 2009
 * Modified : Aug 23, 2009
 * License  : Apache License 2.0 
 */
package net.freestu.looker.monitor;

import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;

import net.freestu.looker.monitor.FetcherException;

/**
 *  下载器的基类
 */
public abstract class AbstractFetcher implements Callable<Object>
{
	
	/**
	 * 下载是否成功
	 */
	protected boolean isSuccess;
	
	/**
	 * 抓取的URL
	 */
	protected URL url;
	
	/**
	 * 网页连接对象
	 */
	protected HttpURLConnection connection;
	
	/**
	 * 闭锁，一个简单的同步工具
	 * 在多线程下载网页或者附件的时候，需要判断是否全部完成，可以使用闭锁
	 */
	 protected CountDownLatch latch;
	 
	
	 /**
	  * 构造函数
	  * @param surl
	  * @param latch
	 * @throws FetcherException 
	  */
	 public AbstractFetcher(String surl, CountDownLatch latch) throws FetcherException
	 {
		 try {
	        this.url   = new URL(surl);
	        this.latch = latch; 
	        this.isSuccess = true;
        } catch (MalformedURLException e) {
	       throw new FetcherException(e.getMessage());
        }
		
	 }
	 
	 /**
	  * 只有URL的构造函数
	  * @param surl
	 * @throws FetcherException 
	  */
	 public AbstractFetcher(String surl) throws FetcherException
	 {
		 try {
		        this.url   = new URL(surl);
		        this.isSuccess = true;
	        } catch (MalformedURLException e) {
		       throw new FetcherException(e.getMessage());
	        }
	 }
	
	/**
	 * 判断下载是否成功
	 */
	public boolean isSuccess()
	{
		return this.isSuccess;
	}
	
	/**
	 * 打开连接
	 * @throws FetcherException 
	 */
	protected void openConnection() throws FetcherException
	{
		try {
		//建立连接
		connection = (HttpURLConnection) url.openConnection();
		//检查返回的状态码
		int code = connection.getResponseCode();
		switch(code)
		{
		case 302://跳转，建立新的URL
			String newUrl = connection.getHeaderField("Location");
			if (newUrl==null){
				isSuccess = false;
				throw new FetcherException("转向文件不存在");
			}else{
				//建立新的连接
				url = new URL(newUrl);
				openConnection();
			}
			break;
		case 404://文件不存在
			isSuccess = false;
			throw new FetcherException("请求文件不存在");
		default:
			break;
		}
		}catch (IOException e) {
			isSuccess = false;
			throw new FetcherException(e.getMessage());
		}
		
	}
	
	/**
	 * 自减闭锁
	 */
	protected void countDownLatch()
	{
		if(latch!=null)
			latch.countDown();
	}
	
	/**
	 * 获取内容
	 * @throws FetcherException
	 */
	public abstract void fetch() throws FetcherException;
	
	/**
	 * 返回抓取的内容
	 * @return
	 */
	public abstract Object getFeched();
	
	/**
	 * 实现call接口
	 */
	public Object call() throws Exception
	{
		try {
	        fetch();
        } catch (FetcherException e) {
	        throw new Exception(e.getMessage());  
        }finally {
        	countDownLatch();
        }
        return getFeched(); 
	}
	
	/**
	 *  设置闭锁
	 */
	public void setLatch(CountDownLatch latch)
	{
		this.latch = latch;
	}
	
	/**
	 * 返回下载的URL
	 */
	public String getUrl()
	{
		return this.url.toString();
	}
	
	/**
	 * 返回输入流
	 * @throws IOException 
	 */
	public OutputStream getOutputStream() throws IOException
	{
		return this.connection.getOutputStream();
	}
}
